void
hap_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
- l1_pgentry_t new, unsigned int level)
+ mfn_t table_mfn, l1_pgentry_t new, unsigned int level)
{
hap_lock(v->domain);
switch ( type ) {
case PGT_l3_page_table:
- paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 4);
+ paging_write_p2m_entry(d, gfn,
+ p2m_entry, *table_mfn, new_entry, 4);
break;
case PGT_l2_page_table:
#if CONFIG_PAGING_LEVELS == 3
/* for PAE mode, PDPE only has PCD/PWT/P bits available */
new_entry = l1e_from_pfn(mfn_x(page_to_mfn(pg)), _PAGE_PRESENT);
#endif
- paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 3);
+ paging_write_p2m_entry(d, gfn,
+ p2m_entry, *table_mfn, new_entry, 3);
break;
case PGT_l1_page_table:
- paging_write_p2m_entry(d, gfn, p2m_entry, new_entry, 2);
+ paging_write_p2m_entry(d, gfn,
+ p2m_entry, *table_mfn, new_entry, 2);
break;
default:
BUG();
entry_content = l1e_empty();
/* level 1 entry */
- paging_write_p2m_entry(d, gfn, p2m_entry, entry_content, 1);
+ paging_write_p2m_entry(d, gfn, p2m_entry, table_mfn, entry_content, 1);
/* Success */
rv = 1;
l1_pgentry_t l1e_content;
l1_pgentry_t *l1e;
l2_pgentry_t *l2e;
+ mfn_t l1mfn;
int i1, i2;
#if CONFIG_PAGING_LEVELS >= 3
l3_pgentry_t *l3e;
{
continue;
}
- l3e = map_domain_page(mfn_x(_mfn(l4e_get_pfn(l4e[i4]))));
+ l3e = map_domain_page(l4e_get_pfn(l4e[i4]));
#endif /* now at levels 3 or 4... */
for ( i3 = 0;
i3 < ((CONFIG_PAGING_LEVELS==4) ? L3_PAGETABLE_ENTRIES : 8);
{
continue;
}
- l2e = map_domain_page(mfn_x(_mfn(l3e_get_pfn(l3e[i3]))));
+ l2e = map_domain_page(l3e_get_pfn(l3e[i3]));
#endif /* all levels... */
for ( i2 = 0; i2 < L2_PAGETABLE_ENTRIES; i2++ )
{
{
continue;
}
- l1e = map_domain_page(mfn_x(_mfn(l2e_get_pfn(l2e[i2]))));
+
+ l1mfn = _mfn(l2e_get_pfn(l2e[i2]));
+ l1e = map_domain_page(mfn_x(l1mfn));
for ( i1 = 0; i1 < L1_PAGETABLE_ENTRIES; i1++, gfn++ )
{
gfn = get_gpfn_from_mfn(mfn);
/* create a new 1le entry using l1e_flags */
l1e_content = l1e_from_pfn(mfn, l1e_flags);
- paging_write_p2m_entry(d, gfn, &l1e[i1], l1e_content, 1);
+ paging_write_p2m_entry(d, gfn, &l1e[i1],
+ l1mfn, l1e_content, 1);
}
unmap_domain_page(l1e);
}
* shadow processing jobs.
*/
void
-shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn, l1_pgentry_t *p,
+shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn,
+ l1_pgentry_t *p, mfn_t table_mfn,
l1_pgentry_t new, unsigned int level)
{
struct domain *d = v->domain;
- mfn_t table_mfn = pagetable_get_mfn(d->arch.phys_table);
mfn_t mfn;
shadow_lock(d);
/* Functions that atomically write PT/P2M entries and update state */
void shadow_write_p2m_entry(struct vcpu *v, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level);
+ l1_pgentry_t *p, mfn_t table_mfn,
+ l1_pgentry_t new, unsigned int level);
int shadow_write_guest_entry(struct vcpu *v, intpte_t *p,
intpte_t new, mfn_t gmfn);
int shadow_cmpxchg_guest_entry(struct vcpu *v, intpte_t *p,
void (*update_cr3 )(struct vcpu *v, int do_locking);
void (*update_paging_modes )(struct vcpu *v);
void (*write_p2m_entry )(struct vcpu *v, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
+ l1_pgentry_t *p, mfn_t table_mfn,
+ l1_pgentry_t new,
unsigned int level);
int (*write_guest_entry )(struct vcpu *v, intpte_t *p,
intpte_t new, mfn_t gmfn);
}
/* Atomically write a P2M entry and update the paging-assistance state
- * appropriately. */
+ * appropriately.
+ * Arguments: the domain in question, the GFN whose mapping is being updated,
+ * a pointer to the entry to be written, the MFN in which the entry resides,
+ * the new contents of the entry, and the level in the p2m tree at which
+ * we are writing. */
static inline void paging_write_p2m_entry(struct domain *d, unsigned long gfn,
- l1_pgentry_t *p, l1_pgentry_t new,
- unsigned int level)
+ l1_pgentry_t *p, mfn_t table_mfn,
+ l1_pgentry_t new, unsigned int level)
{
struct vcpu *v = current;
if ( v->domain != d )
v = d->vcpu[0];
if ( likely(v && paging_mode_enabled(d) && v->arch.paging.mode != NULL) )
{
- return v->arch.paging.mode->write_p2m_entry(v, gfn, p, new, level);
+ return v->arch.paging.mode->write_p2m_entry(v, gfn, p, table_mfn,
+ new, level);
}
else
safe_write_pte(p, new);